////
/// @group tooltip
////

@use "sass:map";
@use "../utils";
@use "../border-radius";
@use "../spacing";
@use "../theme/a11y";
@use "../theme/colors";
@use "../transition/transition";
@use "../typography/typography";

/// Set to `true` to disable all the styles
/// @type Boolean
$disable-everything: false !default;

/// Set to `true` to disable both the `above` and `below` styles.
/// @type Boolean
$disable-vertical: false !default;

/// Set to `true` to disable both the `left` and `right` styles.
/// @type Boolean
$disable-horizontal: false !default;

/// Set to `true` to disable the `position="above"` styles.
/// @type Boolean
$disable-above: $disable-vertical !default;

/// Set to `true` to disable the `position="below"` styles.
/// @type Boolean
$disable-below: $disable-vertical !default;

/// Set to `true` to disable the `position="left"` styles.
/// @type Boolean
$disable-left: $disable-horizontal !default;

/// Set to `true` to disable the `position="right"` styles.
/// @type Boolean
$disable-right: $disable-horizontal !default;

/// Set to `true` to disable the dense styles.
/// @type Boolean
$disable-dense: false !default;

/// The default `Tooltip` background-color.
/// @type Color
$background-color: #616161 !default;

/// The default `Tooltip` text color
/// @type Color
$color: a11y.contrast-color($background-color) !default;

/// The default `Tooltip` typography styles.
/// @type Map
$typography: map.merge(
  typography.$body-1-styles,
  (
    letter-spacing: null,
  )
) !default;

/// The default dense `Tooltip` typography styles which is applied
/// on top of the `$typography` styles.
///
/// @type Map
$dense-typography: (
  font-size: 0.625rem,
  line-height: 0.825rem,
) !default;

/// The default `Tooltip` border radius.
/// @type Number
$border-radius: border-radius.get-var(xs) !default;

/// The default `Tooltip` z-index.
/// @type Number
$z-index: utils.$temporary-element-z-index + 20 !default;

/// The default `max-width` for a `Tooltip`.
/// @type Number
$max-width: 15rem !default;

/// The default `min-height` for a `Tooltip`.
/// @type Number
$min-height: 2rem !default;

/// The default horizontal padding for a `Tooltip`.
/// @type Number
$horizontal-padding: spacing.get-var(md) !default;

/// The default vertical padding for a `Tooltip`
/// @type Number
$vertical-padding: calc(spacing.get-var(sm) * 1.25) !default;

/// The default spacing between a tooltipped element and the `Tooltip`.
/// @type Number
$spacing: 1.5rem !default;

/// The default dense spacing between a tooltipped element and the `Tooltip`.
/// @type Number
$dense-spacing: 0.875rem !default;

/// The default min-height for a dense `Tooltip`.
/// @type Number
$dense-min-height: 1.375rem !default;

/// The default horizontal padding for a dense `Tooltip`.
/// @type Number
$dense-horizontal-padding: spacing.get-var(sm) !default;

/// The default vertical padding for a dense `Tooltip`.
/// @type Number
$dense-vertical-padding: calc(spacing.get-var(xs) * 1.25) !default;

/// The default `Tooltip` enter transition duration.
/// @type Number
$enter-duration: transition.$linear-duration !default;

/// The default `Tooltip` enter transition timing function.
/// @type Number
$enter-timing-function: transition.$deceleration-timing-function !default;

/// The default `Tooltip` leave transition duration.
/// @type Number
$leave-duration: transition.$linear-duration !default;

/// The default `Tooltip` leave transition timing function.
/// @type Number
$leave-timing-function: transition.$acceleration-timing-function !default;

/// The default `Tooltip` enter/leave animation distance.
/// @type Number
$transition-distance: spacing.get-var(sm) !default;

/// The available configurable css variables and mostly used internally for the
/// `get-var`, `set-var`, and `use-var` utils.
/// @type List
$variables: (
  background-color,
  border-radius,
  color,
  spacing,
  z-index,
  horizontal-padding,
  vertical-padding,
  min-height,
  max-width,
  dense-horizontal-padding,
  dense-vertical-padding,
  dense-min-height,
  transition-distance
);

/// @param {String} name - The supported variable name
/// @param {any} fallback [null] - An optional fallback value
/// @returns {String} a `var()` statement
@function get-var($name, $fallback: null) {
  $var: utils.get-var-name($variables, $name, "tooltip");
  @if $fallback {
    @return var(#{$var}, #{$fallback});
  }

  @return var(#{$var});
}

/// @param {String} name - The supported variable name
/// @param {any} value - The value to set the variable to. Supports `null` which
/// will just be a no-op.
@mixin set-var($name, $value) {
  @if $value {
    #{utils.get-var-name($variables, $name, "tooltip")}: #{$value};
  }
}

/// @param {String} property - The css property to apply the variable to
/// @param {String} name [$property] - The supported variable name
/// @param {any} fallback [null] - An optional fallback value if the variable
/// has not been set
@mixin use-var($property, $name: $property, $fallback: null) {
  @if not $fallback {
    @if name == border-radius {
      $fallbacK: $border-radius;
    } @else if name == horizontal-padding {
      $fallback: $horizontal-padding;
    } @else if name == vertical-padding {
      $fallback: $vertical-padding;
    }
  } @else if name == dense-horizontal-padding {
    $fallback: $dense-horizontal-padding;
  } @else if name == dense-vertical-padding {
    $fallback: $dense-vertical-padding;
  } @else if name == transition-distance {
    $fallback: $transition-distance;
  }

  #{$property}: get-var($name, $fallback);
}

/// Conditionally applies the css variables based on feature flags
@mixin variables {
  @if not $disable-everything {
    // do not include spacing

    @include set-var(background-color, $background-color);
    @include set-var(color, $color);
    @include set-var(max-width, $max-width);
    @include set-var(min-height, $min-height);
    @include set-var(z-index, $z-index);

    @if not $disable-dense {
      @include set-var(dense-min-height, $dense-min-height);
    }
  }
}

@mixin dense-variables {
  @if not $disable-everything {
    @include set-var(spacing, $dense-spacing);
    @include set-var(min-height, get-var(dense-min-height));
    @include set-var(
      horizontal-padding,
      get-var(dense-horizontal-padding, $dense-horizontal-padding)
    );
    @include set-var(
      vertical-padding,
      get-var(dense-vertical-padding, $dense-vertical-padding)
    );
  }
}

/// Generates all the styles based on feature flags.
///
/// @param {Boolean} disable-layer [false] - Set this to `true` to disable the
/// layer behavior
@mixin styles($disable-layer: false) {
  @if not $disable-everything {
    @include utils.optional-layer(tooltip, $disable-layer) {
      .rmd-tooltip {
        @include utils.map-to-styles($typography);
        @include use-var(background-color);
        @include use-var(color);
        @include use-var(border-radius, $fallback: $border-radius);
        @include use-var(max-width);
        @include use-var(min-height);
        @include use-var(z-index);

        opacity: 0;
        overflow: hidden;
        overflow-wrap: anywhere;
        padding: get-var(vertical-padding, $vertical-padding)
          get-var(horizontal-padding, $horizontal-padding);
        pointer-events: none;
        position: fixed;
        text-transform: none;
        user-select: none;

        @if not $disable-dense {
          &--dense {
            @include utils.map-to-styles($dense-typography);
            @include dense-variables;
          }
        }

        @if not $disable-above {
          &--above {
            transform: translateY(
              #{utils.negate-var(
                  get-var(transition-distance, $transition-distance)
                )}
            );
          }
        }

        @if not $disable-below {
          &--below {
            transform: translateY(
              #{get-var(transition-distance, $transition-distance)}
            );
          }
        }

        @if not $disable-left {
          &--left {
            transform: translateX(
              #{utils.negate-var(
                  get-var(transition-distance, $transition-distance)
                )}
            );
          }
        }

        @if not $disable-right {
          &--right {
            transform: translateX(
              #{get-var(transition-distance, $transition-distance)}
            );
          }
        }

        &--visible {
          opacity: 1;
          transform: none;
        }

        &--enter {
          transition:
            opacity $enter-duration,
            transform $enter-duration * 2;
          transition-timing-function: $enter-timing-function;
        }

        &--exit {
          transition: opacity $leave-duration $leave-timing-function;
        }

        &--exit-active {
          opacity: 0;
        }
      }
    }
  }
}
